// function React.useMemo<T>(factory: () => T, deps: React.DependencyList | undefined): T
// export function useMemo<T>(factory: () => T, deps: React.DependencyList | undefined): T {}

// React.useMemo(() => <Son />, []);

// react-reconciler/src/ReactFiberHooks
function mountMemo<T>(nextCreate: () => T, deps: React.DependencyList | undefined) {
  const hook = mountWorkInProgressHook();
  const nextDeps = deps === undefined ? null : deps;
  const nextValue = nextCreate();
  hook.memoizedState = [nextValue, nextDeps];
  return nextValue;
}

function updateMemo<T>(nextCreate: () => T, deps: React.DependencyList | undefined) {
  const hook = updateWorkInProgressHook();
  const nextDeps = deps === undefined ? null : deps;
  const prevState = hook.memoizedState;
  if (prevState !== null) {
    // Assume these are defined. If they're not, areHookInputsEqual will warn.
    if (nextDeps !== null) {
      const prevDeps = prevState[1];
      if (areHookInputsEqual(nextDeps, prevDeps)) {
        // 没有依赖没有变 就直接返回
        return prevState[0];
      }
    }
  }
  // 否则就再次执行
  const nextValue = nextCreate();
  hook.memoizedState = [nextValue, nextDeps];
  return nextValue;
}

let workInProgressHook: any = null;

function mountWorkInProgressHook() {
  return workInProgressHook;
}

function updateWorkInProgressHook() {
  return workInProgressHook;
}

function areHookInputsEqual(nextDeps: any, prevDeps: any) {
  if (prevDeps === null) {
    return false;
  }
  for (let i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
    if (Object.is(nextDeps[i], prevDeps[i])) {
      continue;
    }
    return false;
  }
  return true;
}
